package com.example.opengl.camera

import android.app.Activity
import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.opengl.GLES20
import android.opengl.GLES20.*
import android.opengl.GLSurfaceView
import android.os.Build
import android.view.Surface
import androidx.annotation.RequiresApi
import com.android.baselibrary.utils.getScreenHeight
import com.android.baselibrary.utils.getScreenWidth
import com.example.opengl.camera.filter.*
import com.example.opengl.camera.mediarecord.MediaRecordModel
import java.io.File
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

/**
 * @author: Mr.You
 * @create: 2023-07-19 13:40
 * @description:
 **/
open class MyGLRender(myGLSurfaceView: MyGLSurfaceView) : GLSurfaceView.Renderer,
    SurfaceTexture.OnFrameAvailableListener {
    private val mMyGLSurfaceView = myGLSurfaceView
    private var mTextureID: IntArray? = null
    private var mSurfaceTexture: SurfaceTexture? = null
    private var mScreenFilter: ScreenFilter? = null
    private var mCameraFilter: CameraFilter? = null

    private var filterGroup: FilterGroup? = null

    private val mTx: FloatArray = FloatArray(16)

    private var mWidth = 0

    private var mHeight = 0

    private var isInitSurface = true


    private var beautyFilter: BeautyFilter? = null
    private var mCameraHelper: CameraHelper = CameraHelper(
        mMyGLSurfaceView.context as Activity, Camera.CameraInfo.CAMERA_FACING_FRONT,
        getScreenWidth(), getScreenHeight()
    )
    private val mediaRecordModel = MediaRecordModel()

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {


        mTextureID = intArrayOf(1)
        //绑定纹理id
        glGenTextures(mTextureID!!.size, mTextureID, 0)
        mSurfaceTexture = SurfaceTexture(mTextureID!![0])
        mSurfaceTexture?.setOnFrameAvailableListener(this)
        mCameraFilter = CameraFilter()
        mScreenFilter = ScreenFilter()
        filterGroup = FilterGroup()

        /**初始化MediaRecordModel**/
        val file = File(mMyGLSurfaceView.context.cacheDir.absolutePath + File.separator + "record/")
        if (!file.exists()) file.mkdirs()
        val file1 = File(file, System.nanoTime().toString().plus(".mp4"))
        if (!file1.exists()){
           file1.createNewFile()
        }


        mediaRecordModel.setOutFilePath(file1.absolutePath)
        mediaRecordModel.setVideoSize(getScreenWidth(), getScreenHeight())
        mCameraHelper.getCamera()?.let { mediaRecordModel.setCamera(it) }
    }

    open fun changeCamera() {
        mCameraHelper.switchCamera()
    }

    open fun switchFilter(filterType: FilterType) {
        mMyGLSurfaceView.queueEvent {
            filterGroup?.switchFilter(filterType)
        }

    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        this.mHeight = height
        this.mWidth = width
        mCameraHelper.startPreview(mSurfaceTexture)
        mCameraFilter?.onReady(width, height)
        mScreenFilter?.onReady(width, height)
        filterGroup?.onReady(width, height)
    }

    @RequiresApi(Build.VERSION_CODES.M)
    override fun onDrawFrame(gl: GL10?) {
        glClearColor(0F, 0F, 0F, 0F)
        glClear(GL_COLOR_BUFFER_BIT)
        mSurfaceTexture?.updateTexImage()
        mSurfaceTexture?.getTransformMatrix(mTx)
        mCameraFilter?.setMatrix(mTx)
        var textureId = mCameraFilter?.onDrawFrame(mTextureID!![0])
        filterGroup?.setMatrix(mTx)
        textureId = filterGroup?.onDrawFrame(textureId!!)
        if (beautyFilter != null) {
            //  glEnable(GL_SCISSOR_TEST)
            textureId = beautyFilter?.onDrawFrame(textureId!!)
            // glDisable(GL_SCISSOR_TEST)
        }

        textureId = mScreenFilter?.onDrawFrame(textureId!!)


        if (isInitSurface) {
            isInitSurface = false
            mediaRecordModel.setSurface(Surface(mSurfaceTexture!!))
        }


    }


    override fun onFrameAvailable(surfaceTexture: SurfaceTexture?) {
        mMyGLSurfaceView.requestRender()
    }

    fun setBeautyFilter() {
        if (beautyFilter == null) {
            beautyFilter = BeautyFilter()
            beautyFilter?.onReady(mWidth, mHeight)
        }
    }

    fun getCamera(): Camera? {
        return mCameraHelper.getCamera()
    }

    @RequiresApi(Build.VERSION_CODES.N)
    fun setRecordVideo(record: Boolean) {
        if (record){
            mediaRecordModel.startRecord()
        }else{
            mediaRecordModel.stopRecord()
        }
    }
}